package com.zxn.utils;


import java.net.InetAddress;
import java.net.UnknownHostException;

import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.admin.indices.exists.types.TypesExistsResponse;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.xpack.client.PreBuiltXPackTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @author zxn
 * es 管理工具类
 */
@Component
public class ElasticUtils {
    
	 //集群名,默认值elasticsearch
    private static String CLUSTER_NAME="elasticsearch";

    
    //ES集群中某个节点
    private static String HOSTNAME="127.0.0.1";

    //连接端口号
    private static int TCP_PORT=9300;
    

    //构建Settings对象
    private static Settings settings = Settings.builder()
    		.put("cluster.name", CLUSTER_NAME)
            .put("xpack.security.transport.ssl.enabled", false)
            .put("xpack.security.user", "elastic:changeme")
            .put("client.transport.sniff", true).build();
    //TransportClient对象，用于连接ES集群
    private static volatile TransportClient client;

    /**
     * 同步synchronized(*.class)代码块的作用和synchronized static方法作用一样,
     * 对当前对应的*.class进行持锁,static方法和.class一样都是锁的该类本身,同一个监听器
     * @return
     * @throws UnknownHostException
     */
    public static TransportClient getClient(){
        if(client==null){
            synchronized (TransportClient.class){
            	try {
                	client =new  PreBuiltXPackTransportClient(settings)
            			    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(HOSTNAME), TCP_PORT));
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
            }
        }
        return client;
    }

    /**
     * 获取索引管理的IndicesAdminClient
     */
    public static IndicesAdminClient getAdminClient() {
        return getClient().admin().indices();
    }

    /**
     * 判定索引是否存在
     * @param indexName
     * @return
     */
    public static boolean isExists(String indexName){
        IndicesExistsResponse response=getAdminClient().prepareExists(indexName).get();
        return response.isExists()?true:false;
    }
    /**
     * 创建索引
     * @param indexName
     * @return
     */
    public static boolean createIndex(String indexName){
        CreateIndexResponse createIndexResponse = getAdminClient()
                .prepareCreate(indexName.toLowerCase())
                .get();
        return createIndexResponse.isAcknowledged()?true:false;
    }

    /**
     * 创建索引
     * @param indexName 索引名
     * @param shards   分片数
     * @param replicas  副本数
     * @return
     */
    public static boolean createIndex(String indexName, int shards, int replicas) {
        Settings settings = Settings.builder()
                .put("index.number_of_shards", shards)
                .put("index.number_of_replicas", replicas)
                .build();
        CreateIndexResponse createIndexResponse = getAdminClient()
                .prepareCreate(indexName.toLowerCase())
                .setSettings(settings)
                .execute().actionGet();
        return createIndexResponse.isAcknowledged()?true:false;
    }

    /**
     * 位索引indexName设置mapping
     * @param indexName
     * @param typeName
     * @param mapping
     */
    public static void setMapping(String indexName, String typeName, Object mapping) {
        getAdminClient().preparePutMapping(indexName)
                .setType(typeName)
                .setSource(mapping,XContentType.JSON)
                .get();
    }

    /**
     * 删除索引
     * @param indexName
     * @return
     */
    public static boolean deleteIndex(String indexName) {
        DeleteIndexResponse deleteResponse = getAdminClient()
                .prepareDelete(indexName.toLowerCase())
                .execute()
                .actionGet();
        return deleteResponse.isAcknowledged()?true:false;
    }
    /**
     * 判断index下面的类型type 是否存在
     */
    public static boolean isExistsType(String index ,String type){
    	IndicesAdminClient indexs = getAdminClient();
		TypesExistsResponse types =  indexs.prepareTypesExists(index).setTypes(type).get();
		return types.isExists()?true:false;
    }
}
